package people.paper.tv.speech.impl.baidu;

import android.content.Context;
import android.media.AudioManager;
import android.util.Log;

import com.baidu.tts.client.SpeechError;
import com.baidu.tts.client.SpeechSynthesizeBag;
import com.baidu.tts.client.SpeechSynthesizer;
import com.baidu.tts.client.SpeechSynthesizerListener;
import com.baidu.tts.client.TtsMode;

import java.util.ArrayList;
import java.util.List;

import people.paper.tv.speech.SpeechCore;

public class BaiduSpeechCore implements SpeechCore, SpeechSynthesizerListener {
    private final String TAG = "BaiduSpeechCore";
    private final String appId = "11454753"; // "11005757";
    private final String appKey = "rmRbCWG57tRbT3i9cdzmHZfV";       // "Ovcz19MGzIKoDDb3IsFFncG1";
    private final String secretKey = "IdybXnk9P88pIvP7eqnjGdIzpFxxjXVt"; //"e72ebb6d43387fc7f85205ca7e6706e2";
    // TtsMode.MIX; 离在线融合，在线优先； TtsMode.ONLINE 纯在线； 没有纯离线
    private TtsMode ttsMode = TtsMode.ONLINE;
    private SpeechSynthesizer mSpeechSynthesizer;
    private boolean isPalying = false;
    private int talkingID = 0;

    public BaiduSpeechCore(Context context) {
        initTTs(context);
    }

    private void initTTs(Context context) {
        mSpeechSynthesizer = SpeechSynthesizer.getInstance();
        mSpeechSynthesizer.setContext(context);
        mSpeechSynthesizer.setSpeechSynthesizerListener(this);
        int result = mSpeechSynthesizer.setAppId(appId);
        Log.i(TAG, "setAppId result= " + result);
        result = mSpeechSynthesizer.setApiKey(appKey, secretKey);
        Log.i(TAG, "setApiKey result= " + result);
        // 5. 以下setParam 参数选填。不填写则默认值生效
        // 设置在线发声音人： 0 普通女声（默认） 1 普通男声 2 特别男声 3 情感男声<度逍遥> 4 情感儿童声<度丫丫>
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0");
        // 设置合成的音量，0-9 ，默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, "9");
        // 设置合成的语速，0-9 ，默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, "5");
        // 设置合成的语调，0-9 ，默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, "5");

        // 该参数设置为TtsMode.MIX生效。即纯在线模式不生效。
        // MIX_MODE_DEFAULT 默认 ，wifi状态下使用在线，非wifi离线。在线状态下，请求超时6s自动转离线
        // MIX_MODE_HIGH_SPEED_SYNTHESIZE_WIFI wifi状态下使用在线，非wifi离线。在线状态下， 请求超时1.2s自动转离线
        // MIX_MODE_HIGH_SPEED_NETWORK ， 3G 4G wifi状态下使用在线，其它状态离线。在线状态下，请求超时1.2s自动转离线
        // MIX_MODE_HIGH_SPEED_SYNTHESIZE, 2G 3G 4G wifi状态下使用在线，其它状态离线。在线状态下，请求超时1.2s自动转离线
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer.MIX_MODE_DEFAULT);

        //设置播放器的音频流类型，默认值为AudioManager.STREAM_MUSIC, AudioManager.STREAM_MUSIC指的是用与音乐播放的音频流
        mSpeechSynthesizer.setAudioStreamType(AudioManager.MODE_IN_CALL);
        result = mSpeechSynthesizer.initTts(ttsMode);
        Log.i(TAG, "initTts result= " + result);
    }

    private SpeechCoreListener listener;

    @Override
    public void setSpeechCoreListener(SpeechCoreListener listener) {
        this.listener = listener;
    }

    private static final int TEXT_LENGTH = 512;

    @Override
    public int play(String text) {
        int result;
        int length = text.length();
        if (length >= TEXT_LENGTH) {
            List<SpeechSynthesizeBag> bags = new ArrayList<>();
            int c = length / TEXT_LENGTH;
            for (int i = 0; i < c; i++) {
                bags.add(getSpeechSynthesizeBag(text.substring(i * TEXT_LENGTH, (i + 1) * TEXT_LENGTH), String.valueOf(i)));
            }
            bags.add(getSpeechSynthesizeBag(text.substring(c * TEXT_LENGTH, length), String.valueOf(c)));
            result = mSpeechSynthesizer.batchSpeak(bags);
        } else {
            result = mSpeechSynthesizer.speak(text);// 读取单独一个字符串
        }
        Log.i(TAG, "speak result= " + result);
        if (result >= 0)
            return ++talkingID;
        return result;
    }

    @Override
    public int getPlayingID() {
        return talkingID;
    }

    @Override
    public boolean isPlaying() {
        return isPalying;
    }

    private boolean bPaused = false;

    @Override
    public void pause(int id) {
        synchronized (mSpeechSynthesizer) {
            bPaused = true;
            mSpeechSynthesizer.pause();
        }
    }

    @Override
    public boolean isPaused() {
        return bPaused;
    }

    @Override
    public void resume(int id) {
        synchronized (mSpeechSynthesizer) {
            mSpeechSynthesizer.resume();
            bPaused = false;
        }
    }

    @Override
    public boolean stop(int id) {
        int result = mSpeechSynthesizer.stop();
        return result == 0;
    }

    private SpeechSynthesizeBag getSpeechSynthesizeBag(String text, String utteranceId) {
        SpeechSynthesizeBag speechSynthesizeBag = new SpeechSynthesizeBag();
        speechSynthesizeBag.setText(text);
        speechSynthesizeBag.setUtteranceId(utteranceId);
        Log.d(TAG, text + " >>> " + utteranceId);
        return speechSynthesizeBag;
    }

    @Override
    public void onSynthesizeStart(String s) {

    }

    @Override
    public void onSynthesizeDataArrived(String s, byte[] bytes, int i) {

    }

    @Override
    public void onSynthesizeFinish(String s) {

    }

    @Override
    public void onSpeechStart(String s) {
        if (listener != null)
            listener.onStart(talkingID);
    }

    @Override
    public void onSpeechProgressChanged(String s, int i) {
        isPalying = true;
        if (listener != null)
            listener.onPlaying(talkingID, s, i);
    }

    @Override
    public void onSpeechFinish(String s) {
        isPalying = false;
        if (listener != null)
            listener.onComplete(talkingID);
    }

    @Override
    public void release() {
        destroy();
    }

    @Override
    public void onError(String s, SpeechError speechError) {
        Log.i(TAG, "onError " + speechError.toString());
        isPalying = false;
        if (listener != null)
            listener.onStop(talkingID);
    }

    private void destroy() {
        mSpeechSynthesizer.stop();
        mSpeechSynthesizer.release();
        Log.i(TAG, "释放资源成功");
    }
}
